<template>
    <view class="chat-container">
        <!-- 聊天头部 -->
        <view v-if="false" class="chat-header" :style="{ paddingTop: safeTop + 'px' }">
            <view class="header-left">
                <image :src="friendAvatar" class="header-avatar" mode="aspectFill" @click="goToUserProfile"></image>
                <view class="header-info">
                    <text class="friend-name">{{ friendName }}</text>
                    
                </view>
            </view>
            <view class="header-right">
                <tui-icon name="more" size="20" color="#666"></tui-icon>
                <view v-if="unreadCount > 0" class="unread-badge">{{ unreadCount > 99 ? '99+' : unreadCount }}</view>
            </view>
        </view>
        <!-- 重连提示条（已移除，根据需求不再展示） -->

                <!-- 消息列表 -->
        <scroll-view 
            class="message-list" 
            scroll-y 
            :scroll-top="scrollTop"
            :scroll-into-view="lastMessageAnchor"
            :scroll-with-animation="true"
            @scrolltoupper="loadMoreMessages"
            @scroll="onScroll"
            @tap="focusInput"
            :lower-threshold="50"
            :upper-threshold="50"
            :style="{ top: (safeTop + 0) + 'px' }"
        >
            <view class="message-container">
                <!-- 加载更多提示 -->
                <view class="load-more" v-if="loading">
                    <tui-loading size="20" color="#999"></tui-loading>
                    <text class="load-text">加载中...</text>
                    </view>

                <!-- 消息项 -->
                <view 
                    class="message-item" 
                    :class="[item.userType, { 'show-time': item.showTime }]" 
                    v-for="(item, index) in messageList" 
                    :key="item.id || index"
                    :id="'msg-' + (item.id || index)"
                >
                    <!-- 时间显示 -->
                    <view class="message-time" v-if="item.showTime">
                        {{ formatTime(item.createTime) }}
                    </view>

                    <!-- 消息内容 -->
                    <view class="message-content" :class="item.userType">
                        <!-- 对方头像 -->
                        <image 
                            v-if="item.userType === 'friend' && item.avatar" 
                            :src="item.avatar" 
                            class="message-avatar" 
                            mode="aspectFill"
                        ></image>
                        <view v-else-if="item.userType === 'friend'" class="message-avatar text-avatar">客</view>

                        <!-- 消息气泡 -->
                        <view class="message-bubble" :class="item.userType" @longpress="onMessageAction(item)">
                            <text class="message-text">{{ item.content }}</text>
                        </view>

                        <!-- 自己头像 -->
                        <image 
                            v-if="item.userType === 'self' && item.avatar" 
                            :src="item.avatar" 
                            class="message-avatar" 
                            mode="aspectFill"
                        ></image>
                        <view v-else-if="item.userType === 'self'" class="message-avatar text-avatar">我</view>
                    </view>
                </view>

                <!-- 空状态 -->
                <view class="empty-state" v-if="messageList.length === 0 && !loading">
                    <image src="/static/icons/empty-chat.png" class="empty-icon" mode="aspectFit"></image>
                    <text class="empty-text">开始聊天吧~</text>
                </view>
            </view>
        </scroll-view>

        <!-- 新消息提示（不在底部时显示） -->
        <view v-if="showNewMsgTip" class="new-msg-tip" @click="scrollToBottom()">
            <text>有{{ unreadCount }}条新消息，点击查看</text>
        </view>

        <!-- 输入区域 -->
        <view class="input-area">
            <view class="input-container">
                <view class="emoji-btn" :class="{ 'active': showEmojiPanel }" @click="toggleEmojiPanel">
                    <text class="emoji-icon" :style="{ color: showEmojiPanel ? '#007AFF' : '#666' }">😊</text>
                </view>
                <input 
                    v-model="inputText" 
                    class="message-input" 
                    placeholder="输入消息..." 
                    :focus="inputFocus"
                    confirm-type="send"
                    @confirm="sendMessage"
                    @focus="onInputFocus"
                    @blur="onInputBlur"
                />
                <view class="send-btn" :class="{ 'active': inputText.trim() && !sendingInProgress }" @tap="sendMessage" @click="sendMessage" :style="{opacity: (inputText.trim() && !sendingInProgress) ? 1 : 0.6}">
                    <tui-icon name="send" size="20" color="#fff"></tui-icon>
                </view>
            </view>
            
            <!-- 表情面板 -->
            <view class="emoji-panel" v-show="showEmojiPanel" :class="{ 'show': showEmojiPanel }">
                <view class="emoji-header">
                    <text class="emoji-title">选择表情</text>
                    <view class="emoji-close" @click="closeEmojiPanel">
                        <tui-icon name="shut" size="20" color="#666"></tui-icon>
                    </view>
                </view>
                <scroll-view class="emoji-list" scroll-y>
                    <view class="emoji-grid">
                        <view 
                            class="emoji-item" 
                            v-for="(emoji, index) in emojiList" 
                            :key="index"
                            @click="selectEmoji(emoji)"
                        >
                            {{ emoji }}
                        </view>
                    </view>
                </scroll-view>
            </view>
        </view>
    </view>
</template>

<script>
    import cfg from '@/common/config.js'
    export default {
        data() {
            return {
                // 页面参数
                friendId: '', // 对方用户ID（客服聊天无需该值）
                friendName: '在线客服', // 标题显示为客服
                friendAvatar: '/static/img/tabs/my.png', // 客服头像（可替换为客服图标）
                
                // 消息相关
                messageList: [], // 消息列表
                inputText: '', // 输入框内容
                inputFocus: false, // 输入框焦点状态
                
                // 分页相关
                currentPage: 1,
                pageSize: 20,
                total: 0,
                loading: false,
                hasMore: true,
                
                // 滚动相关
                scrollTop: 0,
                isOnline: true, // 在线状态
                isReconnecting: false, // 重连中标记（参考页对齐）
                lastMessageAnchor: '', // 滚动锚点
                lastSendAt: 0, // 发送节流
                isAtBottom: true, // 是否在底部
                showNewMsgTip: false, // 新消息提示
                unreadCount: 0, // 未读计数
                lastReadTime: 0, // 上次已读时间戳（本地）
                safeTop: 0, // 顶部安全区高度
                draftKey: 'kefu_chat_draft',
                sendingInProgress: false, // 发送中标记（用于禁用按钮/类名判断）
                useWS: false, // 彻底关闭 WebSocket，始终走离线轮询
                
                // WebSocket相关
                socketTask: null,
                reconnectTimer: null,
                reconnectCount: 0,
                maxReconnectCount: 5,
                wsConnecting: false, // 正在建立连接
                
                // 用户信息
                userInfo: {},
                token: '',
                preset: '',
                
                // 表情相关
                showEmojiPanel: false,
                
                // 消息轮询
                pollingTimer: null,
                lastMessageTime: 0,
                emojiList: [
                    '😀', '😃', '😄', '😁', '😆', '😅', '😂', '🤣', '😊', '😇',
                    '🙂', '🙃', '😉', '😌', '😍', '🥰', '😘', '😗', '😙', '😚',
                    '😋', '😛', '😝', '😜', '🤪', '🤨', '🧐', '🤓', '😎', '🤩',
                    '🥳', '😏', '😒', '😞', '😔', '😟', '😕', '🙁', '☹️', '😣',
                    '😖', '😫', '😩', '🥺', '😢', '😭', '😤', '😠', '😡', '🤬',
                    '🤯', '😳', '🥵', '🥶', '😱', '😨', '😰', '😥', '😓', '🤗',
                    '🤔', '🤭', '🤫', '🤥', '😶', '😐', '😑', '😬', '🙄', '😯',
                    '😦', '😧', '😮', '😲', '🥱', '😴', '🤤', '😪', '😵', '🤐',
                    '🥴', '🤢', '🤮', '🤧', '😷', '🤒', '🤕', '🤑', '🤠', '😈',
                    '👿', '👹', '👺', '🤡', '💩', '👻', '💀', '☠️', '👽', '👾',
                    '🤖', '🎃', '😺', '😸', '😹', '😻', '😼', '😽', '🙀', '😿',
                    '😾', '👶', '🧒', '👦', '👧', '🧑', '👨', '👩', '🧓', '👴',
                    '👵', '👤', '👥', '👪', '🤳', '💪', '🦾', '🦿', '🦵', '🦶',
                    '👂', '🦻', '👃', '🧠', '🦷', '🦴', '👀', '👁️', '👅', '👄',
                    '💋', '🩸', '💔', '❤️', '🧡', '💛', '💚', '💙', '💜', '🖤',
                    '🤍', '🤎', '💯', '💢', '💥', '💫', '💦', '💨', '🕳️', '💣',
                    '💤', '🔥', '⭐', '🌟', '💫', '✨', '⚡', '☀️', '🌙', '🌚',
                    '🌝', '🌛', '🌜', '🌕', '🌖', '🌗', '🌘', '🌑', '🌒', '🌓',
                    '🌔', '🌍', '🌎', '🌏', '🌋', '🌌', '🌊', '⛰️', '🏔️', '🗻',
                    '🏕️', '🏖️', '🏜️', '🏝️', '🏞️', '🏟️', '🏛️', '🏗️', '🧱', '🏘️',
                    '🏚️', '🏠', '🏡', '🏢', '🏣', '🏤', '🏥', '🏦', '🏧', '🏨',
                    '🏩', '🏪', '🏫', '🏬', '🏭', '🏮', '🏯', '🏰', '💒', '🗼',
                    '🗽', '⛪', '🕌', '🛕', '🕍', '⛩️', '🕋', '⛲', '⛺', '🌉',
                    '🌁', '🚁', '🚂', '🚃', '🚄', '🚅', '🚆', '🚇', '🚈', '🚉',
                    '🚊', '🚝', '🚞', '🚋', '🚌', '🚍', '🚎', '🚐', '🚑', '🚒',
                    '🚓', '🚔', '🚕', '🚖', '🚗', '🚘', '🚙', '🚚', '🚛', '🚜',
                    '🏎️', '🏍️', '🛵', '🛺', '🚲', '🛴', '🛹', '🛼', '🛷', '⛸️',
                    '🥌', '🎿', '🛷', '🛸', '🚀', '🛰️', '💺', '🛩️', '✈️', '🛫',
                    '🛬', '🪂', '💺', '🚁', '🚟', '🚠', '🚡', '⛴️', '🛥️', '🚤',
                    '⛵', '🛶', '🚣', '🏊', '🏄', '🏇', '🧘', '🏃', '🚶', '🧑‍🤝‍🧑',
                    '👫', '👬', '👭', '💑', '👩‍❤️‍👩', '👨‍❤️‍👨', '💏', '👩‍❤️‍💋‍👩', '👨‍❤️‍💋‍👨', '👪',
                    '👨‍👩‍👧', '👨‍👩‍👧‍👦', '👨‍👩‍👦‍👦', '👨‍👩‍👧‍👧', '👨‍👨‍👦', '👨‍👨‍👧', '👨‍👨‍👧‍👦', '👨‍👨‍👦‍👦', '👨‍👨‍👧‍👧', '👩‍👩‍👦',
                    '👩‍👩‍👧', '👩‍👩‍👧‍👦', '👩‍👩‍👦‍👦', '👩‍👩‍👧‍👧', '👨‍👦', '👨‍👦‍👦', '👨‍👧', '👨‍👧‍👦', '👨‍👧‍👧', '👩‍👦',
                    '👩‍👦‍👦', '👩‍👧', '👩‍👧‍👦', '👩‍👧‍👧', '🗣️', '👤', '👥', '👣', '🐵', '🐒',
                    '🦍', '🦧', '🐶', '🐕', '🦮', '🐕‍🦺', '🐩', '🐺', '🦊', '🦝',
                    '🐱', '🐈', '🦁', '🐯', '🐅', '🐆', '🐴', '🐎', '🦄', '🦓',
                    '🦌', '🐮', '🐂', '🐃', '🐄', '🐷', '🐖', '🐗', '🐽', '🐑',
                    '🐐', '🐪', '🐫', '🦙', '🦒', '🐘', '🦏', '🦛', '🐭', '🐁',
                    '🐀', '🐹', '🐰', '🐇', '🐿️', '🦔', '🦇', '🐻', '🐨', '🐼',
                    '🦥', '🦦', '🦨', '🦘', '🦡', '🐾', '🦃', '🐔', '🐓', '🐣',
                    '🐤', '🐥', '🐦', '🐧', '🕊️', '🦅', '🦆', '🦢', '🦉', '🦩',
                    '🦚', '🦜', '🐸', '🐊', '🐢', '🦎', '🐍', '🐲', '🐉', '🦕',
                    '🦖', '🐳', '🐋', '🐬', '🐟', '🐠', '🐡', '🦈', '🐙', '🐚',
                    '🐌', '🐛', '🐜', '🐝', '🐞', '🦗', '🕷️', '🕸️', '🦂', '🦟',
                    '🦠', '💐', '🌸', '💮', '🏵️', '🌹', '🥀', '🌺', '🌻', '🌼',
                    '🌷', '🌱', '🌲', '🌳', '🌴', '🌵', '🌶️', '🌷', '🌸', '🌹',
                    '🌺', '🌻', '🌼', '🌽', '🌾', '🌿', '🍀', '🍁', '🍂', '🍃',
                    '🍇', '🍈', '🍉', '🍊', '🍋', '🍌', '🍍', '🥭', '🍎', '🍏',
                    '🍐', '🍑', '🍒', '🍓', '🫐', '🥝', '🍅', '🫒', '🥥', '🥑',
                    '🍆', '🥔', '🥕', '🌽', '🌶️', '🫑', '🥒', '🥬', '🥦', '🧄',
                    '🧅', '🍄', '🥜', '🌰', '🍞', '🥐', '🥖', '🫓', '🥨', '🥯',
                    '🥞', '🧇', '🧀', '🍖', '🍗', '🥩', '🥓', '🍔', '🍟', '🍕',
                    '🌭', '🥪', '🌮', '🌯', '🫔', '🥙', '🧆', '🥚', '🍳', '🥘',
                    '🍲', '🫕', '🥣', '🥗', '🍿', '🧈', '🧂', '🥫', '🍱', '🍘',
                    '🍙', '🍚', '🍛', '🍜', '🍝', '🍠', '🍢', '🍣', '🍤', '🍥',
                    '🥮', '🍡', '🥟', '🥠', '🥡', '🦀', '🦞', '🦐', '🦑', '🦪',
                    '🍦', '🍧', '🍨', '🍩', '🍪', '🎂', '🍰', '🧁', '🥧', '🍫',
                    '🍬', '🍭', '🍮', '🍯', '🍼', '🥛', '☕', '🫖', '🍵', '🍶',
                    '🍾', '🍷', '🍸', '🍹', '🍺', '🍻', '🥂', '🥃', '🥤', '🧋',
                    '🧃', '🧉', '🧊', '🥢', '🍽️', '🍴', '🥄', '🔪', '🏺'
                ]
            };
        },
        onLoad(options) {
            // 客服聊天：统一显示“在线客服”；允许外部传入标题/头像覆盖
            // this.friendName = this.decodeParam(options.name || '') || '在线客服';
            this.friendAvatar = options.avatar || '/static/img/tabs/my.png';
            // 预置首条消息（与参考页一致）
            if (options.preset) {
                try { this.preset = decodeURIComponent(options.preset); } catch(e) { this.preset = options.preset; }
            }
            
            uni.setNavigationBarTitle({ title: this.friendName });
            
            // 获取用户信息和 token
            this.userInfo = uni.getStorageSync('userInfo') || {};
            this.token = uni.getStorageSync('userToken') || '';
            // 读取本地上次已读时间
            const last = uni.getStorageSync('kefu_last_read_time');
            this.lastReadTime = typeof last === 'number' ? last : 0;
            // 不再恢复草稿，进入页面始终空输入框，并清理历史草稿
            this.inputText = '';
            try { uni.removeStorageSync && uni.removeStorageSync(this.draftKey); } catch (e) {}
            // 计算安全区顶部（小程序导航占位）
            try {
                const systemInfo = uni.getSystemInfoSync();
                this.safeTop = (systemInfo.safeAreaInsets && systemInfo.safeAreaInsets.top) ? systemInfo.safeAreaInsets.top : 0;
            } catch(e) { this.safeTop = 0; }
            
            // 初始化聊天
            this.initChat();
        },
        
        onShow() {
            // 页面显示时自动聚焦输入框
            uni.setNavigationBarTitle({ title: this.friendName || '在线客服' });
            setTimeout(() => {
                this.inputFocus = true;
            }, 500);
            // 返回前台时，若未在线且有 token，尝试建立 WebSocket 连接；否则继续轮询
            try {
                this.userInfo = uni.getStorageSync('userInfo') || this.userInfo || {};
                this.token = uni.getStorageSync('userToken') || this.token || '';
            } catch (e) {}
            if (this.token) {
                this.connectWebSocket();
            } else {
                this.startMessagePolling();
            }
        },
        onHide() {
            // 切后台保存阅读进度与草稿
            try {
                this.markAllRead();
                if (this.inputText && this.inputText.trim()) {
                    uni.setStorageSync(this.draftKey, this.inputText);
                }
            } catch (e) {}
            // 释放实时连接资源，回到前台会在 onShow 自动重连或轮询
            this.closeWebSocket();
            this.stopMessagePolling();
        },
        
        onUnload() {
            // 页面卸载时关闭WebSocket连接和停止轮询
            this.closeWebSocket();
            this.stopMessagePolling();
        },
        methods: {
            // 初始化聊天
            initChat() {
                // 先加载历史消息
                this.loadMessageList();
                // 根据 token 决定实时通道：优先 WebSocket，失败自动降级轮询
                try {
                    this.userInfo = uni.getStorageSync('userInfo') || this.userInfo || {};
                    this.token = uni.getStorageSync('userToken') || this.token || '';
                } catch (e) {}
                if (this.token) {
                    this.connectWebSocket();
                } else {
                    this.startMessagePolling();
                }
            },
            // 解析后端文本内容，兼容 {"text":"xxx"} / {content:"xxx"} / 纯字符串
            parseContent(raw) {
                try {
                    if (raw == null) return '';
                    if (typeof raw === 'string') {
                        const s = raw.trim();
                        if (s.startsWith('{') && s.endsWith('}')) {
                            const obj = JSON.parse(s);
                            if (obj && typeof obj === 'object') {
                                if (obj.text) return String(obj.text).replace(/\n/g, '\n');
                                if (obj.content) return String(obj.content).replace(/\n/g, '\n');
                            }
                        }
                        return s;
                    }
                    if (typeof raw === 'object') {
                        if (raw.text) return String(raw.text);
                        if (raw.content) return String(raw.content);
                        return JSON.stringify(raw);
                    }
                    return String(raw);
                } catch (e) {
                    return String(raw);
                }
            },
            
            // 客服模式无需获取对方资料
            getFriendInfo() {},

            // 解码路由参数（兼容多次 encode 与 + 号空格）
            decodeParam(str) {
                if (!str || typeof str !== 'string') return '';
                let s = str.replace(/\+/g, ' ');
                try {
                    for (let i = 0; i < 2 && /%[0-9A-F]{2}/i.test(s); i++) s = decodeURIComponent(s);
                } catch (e) {}
                return s;
            },
            
            // 获取用户头像
            getUserAvatar(user) {
                if (user.cover && Array.isArray(user.cover) && user.cover.length > 0) {
                    return user.cover[0];
                }
                return '/static/img/tabs/my.png';
            },
            
            // 连接 WebSocket（与参考页一致的实时通道）
            connectWebSocket() {
                try {
                    if (this.wsConnecting || (this.socketTask && this.isOnline)) return;
                    const wsUrl = `wss://www.liujianggongyi.site/app-api/infra/ws?token=${this.token}`;
                    console.log('尝试连接WebSocket:', wsUrl);
                    this.wsConnecting = true;
                    
                    this.socketTask = uni.connectSocket({
                        url: wsUrl,
                        success: () => {
                            console.log('WebSocket连接请求已发送');
                        },
                        fail: (err) => {
                            console.error('WebSocket连接失败:', err);
                            this.handleWebSocketError();
                        }
                    });

                    this.socketTask.onOpen(async () => {
                        console.log('WebSocket连接成功');
                        this.reconnectCount = 0;
                        this.isOnline = true;
                        this.isReconnecting = false;
                        this.wsConnecting = false;
                        // 连接成功后发送预置消息
                        if (this.preset) {
                            try {
                                await this.$api.req('/promotion/kefu-message/send', {
                                    contentType: 1,
                                    content: this.preset
                                }, 'POST', 'JSON', false);
                                this.preset = '';
                                this.refreshMessageList();
                            } catch (e) {}
                        }
                    });

                    this.socketTask.onMessage((res) => {
                        console.log('收到WebSocket消息:', res);
                        this.handleWebSocketMessage(res.data);
                    });

                    this.socketTask.onError((err) => {
                        console.error('WebSocket错误:', err);
                        this.wsConnecting = false;
                        this.handleWebSocketError();
                    });

                    this.socketTask.onClose(() => {
                        console.log('WebSocket连接关闭');
                        this.isOnline = false;
                        this.isReconnecting = true;
                        this.wsConnecting = false;
                        this.autoReconnect();
                    });

                } catch (error) {
                    console.error('WebSocket连接异常:', error);
                    this.handleWebSocketError();
                }
            },
            
            // 处理WebSocket消息（兼容参考页 KEFU 消息格式）
            handleWebSocketMessage(data) {
                try {
                    const payload = JSON.parse(data);
                    // 参考页使用 WebSocketMessageTypeConstants.KEFU_MESSAGE_TYPE
                    if (payload && payload.type === 'KEFU_MESSAGE_TYPE') {
                        const content = payload.content ? JSON.parse(payload.content) : {};
                        this.addMessage({
                            id: content.id || Date.now(),
                            content: this.parseContent(content.content || content.text),
                            userType: content.senderType === 1 ? 'self' : 'friend',
                            avatar: content.senderType === 1 ? (this.userInfo.avatar || '/static/img/tabs/my.png') : this.friendAvatar,
                            createTime: content.createTime || Date.now(),
                            showTime: (this.messageList.length === 0) ? true : this.shouldShowTime(content.createTime || Date.now(), this.messageList[this.messageList.length - 1].createTime)
                        });
                        return;
                    }
                    if (payload && payload.type === 'KEFU_MESSAGE_ADMIN_READ') {
                        // 管理员已读：标记我方消息为已读
                        this.messageList = this.messageList.map(m => ({
                            ...m,
                            isRead: m.userType === 'self' ? true : m.isRead
                        }));
                        return;
                    }
                    // 兼容旧格式：直接是消息实体
                    const message = payload;
                    if (message && message.content) {
                        this.addMessage({
                            id: message.id || Date.now(),
                            content: this.parseContent(message.content),
                            userType: message.senderType === 1 ? 'self' : 'friend',
                            avatar: message.senderType === 1 ? (this.userInfo.avatar || '/static/img/tabs/my.png') : this.friendAvatar,
                            createTime: message.createTime || Date.now(),
                            showTime: (this.messageList.length === 0) ? true : this.shouldShowTime(message.createTime || Date.now(), this.messageList[this.messageList.length - 1].createTime)
                        });
                    }
                } catch (error) {
                    console.error('解析WebSocket消息失败:', error);
                }
            },
            
            // 处理WebSocket错误
            handleWebSocketError() {
                // 静默降级为离线模式，不再弹提示
                this.isOnline = false;
                this.isReconnecting = false;
                this.wsConnecting = false;
                this.startMessagePolling();
            },

            // 自动重连
            autoReconnect() {
                if (this.reconnectCount < this.maxReconnectCount) {
                    this.reconnectCount++;
                    console.log(`尝试重连第${this.reconnectCount}次`);
                    
                    this.reconnectTimer = setTimeout(() => {
                        this.connectWebSocket();
                    }, 3000 * this.reconnectCount);
                } else {
                    // 超过最大重连次数，降级为轮询
                    this.isReconnecting = false;
                    this.wsConnecting = false;
                    this.startMessagePolling();
                    // 静默降级，不提示
                }
            },
            
            // 关闭WebSocket连接
            closeWebSocket() {
                if (this.reconnectTimer) {
                    clearTimeout(this.reconnectTimer);
                    this.reconnectTimer = null;
                }
                
                if (this.socketTask) {
                    this.socketTask.close();
                    this.socketTask = null;
                }
            },

            // 加载消息列表
            loadMessageList() {
                if (this.loading || !this.hasMore) return;
                
                this.loading = true;

                this.$api.req(`/promotion/kefu-message/page`, {
                    pageNo: this.currentPage,
                    pageSize: this.pageSize,
                    opsUserId: -1 // 客服会话：后端要求传 -1 表示与系统客服对话
                }, 'GET', 'JSON', false)
                    .then(res => {
                    if (res.code === 0 && res.data) {
                        const newMessages = res.data.list.map((msg, index) => ({
                            id: msg.id || Date.now() + index,
                            content: this.parseContent(msg.content),
                            userType: msg.senderType === 1 ? 'self' : 'friend',
                                avatar: msg.senderType === 1 ? (this.userInfo.avatar || '/static/img/tabs/my.png') : this.friendAvatar,
                            createTime: msg.createTime,
                            showTime: false
                        }));

                            if (this.currentPage === 1) {
                            this.messageList = newMessages.reverse();
                            // 记录最新消息时间
                            if (newMessages.length > 0) {
                                this.lastMessageTime = newMessages[newMessages.length - 1].createTime;
                            }
                            // 统一计算各条消息是否展示时间
                            this.recomputeShowTime();
                            // 定位首条未读
                            const unreadIdx = this.messageList.findIndex(m => m.createTime > this.lastReadTime);
                            if (unreadIdx > 0) {
                                const target = this.messageList[unreadIdx];
                                this.lastMessageAnchor = 'msg-' + (target.id || unreadIdx);
                                this.isAtBottom = false;
                                this.unreadCount = this.messageList.length - unreadIdx;
                                this.showNewMsgTip = this.unreadCount > 0;
                            } else {
                                this.scrollToBottom();
                            }
                        } else {
                            this.messageList = [...newMessages.reverse(), ...this.messageList];
                            this.recomputeShowTime();
                            }

                            this.total = res.data.total;
                        this.hasMore = this.messageList.length < this.total;
                        }
                    })
                    .catch(err => {
                    console.error('加载消息失败:', err);
                    uni.showToast({
                        title: '加载消息失败',
                        icon: 'none'
                    });
                    })
                    .finally(() => {
                        this.loading = false;
                    });
            },

            // 发送消息（使用与参考页一致的接口定义）
            sendMessage() {
                // if (!this.inputText.trim() || this.sendingInProgress || !this.isOnline) return;
                const nowTs = Date.now();
                if (nowTs - this.lastSendAt < 400) return; // 发送节流
                this.lastSendAt = nowTs;
                
                const messageContent = this.inputText.trim();
                this.inputText = '';
                
                // 先添加到本地消息列表
                const tempMessage = {
                    id: 'temp_' + Date.now(),
                    content: messageContent,
                    userType: 'self',
                    avatar: this.userInfo.avatar || '/static/img/tabs/my.png',
                    createTime: Date.now(),
                    showTime: (this.messageList.length === 0) ? true : this.shouldShowTime(Date.now(), this.messageList[this.messageList.length - 1].createTime),
                    isSending: true,
                    isRead: false,
                    isFailed: false
                };
                
                this.addMessage(tempMessage);
                
                // 发送到服务器（参考页：KeFuApi.sendKefuMessage）
                this.sendingInProgress = true;
                this.$api.req('/promotion/kefu-message/send', {
                    contentType: 1, // TEXT
                    content: messageContent,
                    opsUserId: -1 // 指定客服会话目标
                }, 'POST', 'JSON', false)
                .then(res => {
                    if (res.code === 0) {
                        // 发送成功，更新消息状态
                        this.updateMessageStatus(tempMessage.id, false);
                        // 刷新消息列表
                        this.refreshMessageList();
                    } else {
                        throw new Error(res.msg || '发送失败');
                    }
                })
                .catch(err => {
                    console.error('发送消息失败:', err);
                    // 发送失败，更新消息状态
                    this.updateMessageStatus(tempMessage.id, false, true);
                    uni.showToast({
                        title: '发送失败',
                        icon: 'none'
                    });
                })
                .finally(() => {
                    this.sendingInProgress = false;
                    // 发送完成后保持输入框为空并聚焦，同时清除本地草稿
                    this.inputText = '';
                    try { uni.removeStorageSync && uni.removeStorageSync(this.draftKey); } catch (e) {}
                    setTimeout(() => {
                        this.inputFocus = true;
                    }, 100);
                });
            },
            
            // 添加消息到列表
            addMessage(message) {
                this.messageList.push(message);
                if (this.isAtBottom || message.userType === 'self') {
                    // 在底部或自己发送的消息，直接滚到底
                    this.scrollToBottom(message);
                    this.showNewMsgTip = false;
                    this.unreadCount = 0;
                } else {
                    // 非底部收到新消息，展示提示
                    this.showNewMsgTip = true;
                    this.unreadCount += 1;
                }
                // 延迟再次滚动，确保DOM完全更新
                setTimeout(() => {
                    if (this.isAtBottom || message.userType === 'self') {
                        this.scrollToBottom(message);
                    }
                }, 200);
            },
            
            // 更新消息状态
            updateMessageStatus(messageId, isSending, isFailed = false) {
                const message = this.messageList.find(msg => msg.id === messageId);
                if (message) {
                    message.isSending = isSending;
                    message.isFailed = isFailed;
                }
            },
            
            // 刷新消息列表
            refreshMessageList() {
                this.currentPage = 1;
                this.hasMore = true;
                this.loadMessageList();
            },

            // 滚动到消息底部
            scrollToBottom(message) {
                this.$nextTick(() => {
                    if (message && (message.id || message.tempId)) {
                        this.lastMessageAnchor = 'msg-' + (message.id || message.tempId);
                    } else if (this.messageList.length) {
                        const last = this.messageList[this.messageList.length - 1];
                        this.lastMessageAnchor = 'msg-' + (last.id || (this.messageList.length - 1));
                    }
                    this.isAtBottom = true;
                    this.showNewMsgTip = false;
                    this.unreadCount = 0;
                });
            },

            // 监听滚动，判断是否在底部
            onScroll(e) {
                try {
                    const top = e.detail.scrollTop || 0;
                    const sh = e.detail.scrollHeight || 0;
                    const ch = e.detail.clientHeight || e.detail.height || 0;
                    if (sh && ch) {
                        // 距底小于 60rpx 认为在底部
                        this.isAtBottom = (sh - ch - top) < 60;
                        if (this.isAtBottom) {
                            this.showNewMsgTip = false;
                            this.unreadCount = 0;
                            this.markAllRead();
                        }
                    }
                } catch (err) {}
            },

            // 标记所有消息为已读并持久化最后一条时间
            markAllRead() {
                if (!this.messageList.length) return;
                const last = this.messageList[this.messageList.length - 1];
                if (last && last.createTime && last.createTime > this.lastReadTime) {
                    this.lastReadTime = last.createTime;
                    uni.setStorageSync('kefu_last_read_time', this.lastReadTime);
                }
            },

            // 加载更多消息
            loadMoreMessages() {
                const now = Date.now();
                if (!this._lastMoreTs) this._lastMoreTs = 0;
                if (now - this._lastMoreTs < 500) return; // 简单节流
                if (!this.loading && this.hasMore && !this.isReconnecting) {
                    this._lastMoreTs = now;
                    this.currentPage += 1;
                    this.loadMessageList();
                }
            },
            
            // 判断是否显示时间（与上一条比较，超5分钟或跨天则显示）
            shouldShowTime(currentTs, prevTs = null) {
                if (!prevTs) return true;
                const cur = Number(currentTs);
                const prev = Number(prevTs);
                if (!isFinite(cur) || !isFinite(prev)) return true;
                const curD = new Date(cur);
                const prevD = new Date(prev);
                const isSameDay = curD.getFullYear() === prevD.getFullYear() && curD.getMonth() === prevD.getMonth() && curD.getDate() === prevD.getDate();
                if (!isSameDay) return true;
                return (cur - prev) > 5 * 60 * 1000;
            },

            // 统一为当前列表计算 showTime
            recomputeShowTime() {
                let prevTs = null;
                for (let i = 0; i < this.messageList.length; i++) {
                    const m = this.messageList[i];
                    const show = this.shouldShowTime(m.createTime, prevTs);
                    this.$set(this.messageList[i], 'showTime', show);
                    prevTs = m.createTime;
                }
            },

            // 格式化时间显示
            formatTime(timestamp) {
                const now = new Date();
                const messageTime = new Date(timestamp);
                const diff = now.getTime() - messageTime.getTime();
                
                // 今天
                if (diff < 24 * 60 * 60 * 1000 && messageTime.getDate() === now.getDate()) {
                    return messageTime.toLocaleTimeString('zh-CN', { 
                        hour: '2-digit', 
                        minute: '2-digit' 
                    });
                }
                
                // 昨天
                const yesterday = new Date(now);
                yesterday.setDate(yesterday.getDate() - 1);
                if (messageTime.getDate() === yesterday.getDate()) {
                    return '昨天 ' + messageTime.toLocaleTimeString('zh-CN', { 
                        hour: '2-digit', 
                        minute: '2-digit' 
                    });
                }
                
                // 更早的日期 - 显示年月日时分秒
                return messageTime.toLocaleString('zh-CN', { 
                    year: 'numeric',
                    month: '2-digit', 
                    day: '2-digit',
                    hour: '2-digit', 
                    minute: '2-digit',
                    second: '2-digit'
                });
            },
            
            // 输入框焦点事件
            onInputFocus() {
                this.inputFocus = true;
                // 延迟滚动，等待键盘弹起
                setTimeout(() => {
                    this.scrollToBottom();
                }, 500);
            },
            
            onInputBlur() {
                // 不要立即设置inputFocus为false，避免发送消息后失去焦点
                // this.inputFocus = false;
                // 取消草稿保存
            },
            
            // 点击消息处理
            msgClick(message) {
                // 点击失败消息重试发送
                if (message && message.isFailed && !this.sendingInProgress) {
                    this.inputText = message.content;
                    // 从列表移除失败的临时消息
                    this.messageList = this.messageList.filter(m => m.id !== message.id);
                    this.$nextTick(() => this.sendMessage());
                }
            },

            // 长按消息：复制/删除（对齐参考页常见操作）
            onMessageAction(message) {
                const itemList = [];
                if (message && message.content) itemList.push('复制');
                if (message && message.userType === 'self') itemList.push('删除');
                if (!itemList.length) return;
                uni.showActionSheet({
                    itemList,
                    success: (res) => {
                        const choice = itemList[res.tapIndex];
                        if (choice === '复制') {
                            uni.setClipboardData({ data: message.content });
                        } else if (choice === '删除') {
                            this.messageList = this.messageList.filter(m => m.id !== message.id);
                        }
                    }
                });
            },
            
            // 聚焦输入框
            focusInput() {
                this.inputFocus = true;
            },
            
            // 切换表情面板
            toggleEmojiPanel() {
                this.showEmojiPanel = !this.showEmojiPanel;
                if (this.showEmojiPanel) {
                    // 关闭键盘
                    this.inputFocus = false;
                } else {
                    // 重新聚焦输入框
                    setTimeout(() => {
                        this.inputFocus = true;
                    }, 100);
                }
            },
            
            // 关闭表情面板
            closeEmojiPanel() {
                this.showEmojiPanel = false;
                // 重新聚焦输入框
                setTimeout(() => {
                    this.inputFocus = true;
                }, 100);
            },
            
            // 选择表情
            selectEmoji(emoji) {
                this.inputText += emoji;
                // 选择表情后关闭面板并重新聚焦输入框
                this.showEmojiPanel = false;
                setTimeout(() => {
                    this.inputFocus = true;
                }, 200);
            },
            
            // 启动消息轮询（已改为 WebSocket，默认不启用）
            startMessagePolling() {
                // 留作降级备用：每3秒检查一次新消息
                if (this.pollingTimer) return;
                this.pollingTimer = setInterval(() => {
                    this.checkNewMessages();
                }, 3000);
            },
            
            // 停止消息轮询
            stopMessagePolling() {
                if (this.pollingTimer) {
                    clearInterval(this.pollingTimer);
                    this.pollingTimer = null;
                }
            },
            
            // 检查新消息
            checkNewMessages() {
                if (!this.userInfo.id) return;
                
                this.$api.req(`/promotion/kefu-message/page`, {
                    pageNo: 1,
                    pageSize: 10,
                    opsUserId: -1
                }, 'GET', 'JSON', false)
                    .then(res => {
                        if (res.code === 0 && res.data && res.data.list.length > 0) {
                            const latestMessage = res.data.list[0];
                            const latestTime = latestMessage.createTime;
                            
                            // 如果有新消息
                            if (latestTime > this.lastMessageTime) {
                                this.lastMessageTime = latestTime;
                                // 重新加载消息列表
                                this.refreshMessageList();
                            }
                        }
                    })
                    .catch(err => {
                        console.error('轮询消息失败:', err);
                    });
            },
            
            // 跳转到用户主页
            goToUserProfile() {
                if (this.friendId) {
                    this.f.nav(`/subPackage1/marriageDetail/marriageDetail?id=${this.friendId}`);
                }
            }
        },
    };
</script>

<style lang="scss" scoped>
    .chat-container {
        display: flex;
        flex-direction: column;
        height: 100vh;
        background: #f5f5f5;
    }

    /* 聊天头部 - 固定 */
    .chat-header {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 20rpx 30rpx;
                background: #fff;
        border-bottom: 1rpx solid #e5e5e5;
        box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
        z-index: 100;

        .header-left {
            display: flex;
            align-items: center;
            flex: 1;
        }

        .header-avatar {
            width: 80rpx;
            height: 80rpx;
            border-radius: 50%;
            margin-right: 20rpx;
            cursor: pointer;
            transition: opacity 0.2s;
            
            &:active {
                opacity: 0.7;
            }
        }

        .header-info {
        display: flex;
        flex-direction: column;
        }

        .friend-name {
            font-size: 32rpx;
            font-weight: 600;
            color: #333;
            margin-bottom: 8rpx;
        }

        .online-status {
            font-size: 24rpx;
            color: #4CAF50;
        }

        .header-right {
            padding: 10rpx;
            position: relative;
        }
    }

    .unread-badge {
        position: absolute;
        right: -8rpx;
        top: -8rpx;
        min-width: 28rpx;
        height: 28rpx;
        border-radius: 14rpx;
        background: #ff4d4f;
        color: #fff;
        font-size: 20rpx;
        line-height: 28rpx;
        text-align: center;
        padding: 0 6rpx;
    }

    /* 消息列表 */
    .message-list {
        position: fixed;
        top: 100rpx; /* 头部高度 */
        left: 0;
        right: 0;
        bottom: 120rpx; /* 输入区域高度 */
        background: #ededed;
    }

    .reconnect-bar {
        position: fixed;
        top: 100rpx;
        left: 0;
        right: 0;
        background: rgba(0,0,0,0.05);
        color: #666;
        font-size: 24rpx;
        text-align: center;
        padding: 10rpx 0;
        z-index: 120;
    }

    .message-container {
        padding: 20rpx 30rpx 200rpx;
        min-height: 100%;
    }

    .new-msg-tip {
        position: fixed;
        right: 20rpx;
        bottom: 140rpx;
        background: #007AFF;
        color: #fff;
        padding: 12rpx 20rpx;
        border-radius: 24rpx;
        font-size: 24rpx;
        box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.12);
        z-index: 130;
    }

    /* 加载更多 */
    .load-more {
        display: flex;
        align-items: center;
        justify-content: center;
            padding: 20rpx;
        margin-bottom: 20rpx;

        .load-text {
            margin-left: 10rpx;
            font-size: 24rpx;
            color: #999;
        }
    }

    /* 消息项 */
    .message-item {
        margin-bottom: 30rpx;

        &.show-time {
            .message-time {
                display: block;
            }
        }

        .message-time {
            display: none;
            text-align: center;
            font-size: 22rpx;
            color: #9aa0a6;
            margin-bottom: 20rpx;
            padding: 8rpx 16rpx;
            background: rgba(0, 0, 0, 0.06);
            border-radius: 24rpx;
            margin-left: auto;
            margin-right: auto;
            width: fit-content;
        }

        .message-content {
            display: flex;
            align-items: flex-end;
            max-width: 100%;

            &.self {
                flex-direction: row-reverse;
            }
        }

        .message-avatar {
            width: 64rpx;
            height: 64rpx;
            border-radius: 50%;
            margin: 0 16rpx;
            flex-shrink: 0;
        }

    /* 文字头像（优雅降级） */
    .text-avatar {
        background: linear-gradient(135deg, #8ec5fc 0%, #e0c3fc 100%);
        color: #fff;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 30rpx;
        font-weight: 600;
        box-shadow: 0 2rpx 6rpx rgba(0,0,0,0.08);
    }

        .message-bubble {
            max-width: 60%;
            padding: 16rpx 20rpx;
            border-radius: 16rpx;
            position: relative;
            word-wrap: break-word;
            box-shadow: 0 2rpx 6rpx rgba(0,0,0,0.04);

            &.self {
                background: #dbeafe; /* 淡蓝 */
                color: #111;
                border-bottom-right-radius: 8rpx;

                &::after {
                    content: '';
                    position: absolute;
                    right: -8rpx;
                    bottom: 8rpx;
                    width: 0;
                    height: 0;
                    border: 8rpx solid transparent;
                    border-left-color: #dbeafe;
                }
            }

            &.friend {
                background: #fff;
                color: #333;
                border: 1rpx solid #eaeaea;
                border-bottom-left-radius: 8rpx;

                &::after {
                    content: '';
                    position: absolute;
                    left: -8rpx;
                    bottom: 8rpx;
                    width: 0;
                    height: 0;
                    border: 8rpx solid transparent;
                    border-right-color: #fff;
                }
            }
        }

        .message-text {
            font-size: 28rpx;
            line-height: 1.4;
            word-break: break-all;
        }
    }

    /* 已读/发送状态已移除 */

    /* 空状态 */
    .empty-state {
        display: flex;
        flex-direction: column;
            align-items: center;
        justify-content: center;
        padding: 100rpx 0;

        .empty-icon {
            width: 200rpx;
            height: 200rpx;
            margin-bottom: 30rpx;
            opacity: 0.5;
        }

        .empty-text {
            font-size: 28rpx;
            color: #999;
        }
    }

    /* 输入区域 - 固定 */
    .input-area {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        background: #f7f7f7;
        border-top: 1rpx solid #ececec;
        box-shadow: 0 -2rpx 8rpx rgba(0, 0, 0, 0.1);
        padding: 20rpx 30rpx;
        padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
        z-index: 100;
    }

    .input-container {
        display: flex;
        align-items: center;
        background: #fff;
        border-radius: 28rpx;
        padding: 10rpx 20rpx;
        border: 1rpx solid #e6e6e6;
    }

    .emoji-btn {
        width: 60rpx;
        height: 60rpx;
        border-radius: 50%;
        background: transparent;
        display: flex;
        align-items: center;
        justify-content: center;
        margin-right: 10rpx;
        transition: all 0.3s ease;
        position: relative;

        &:active {
            background: rgba(0, 122, 255, 0.1);
            transform: scale(0.95);
        }

        &.active {
            background: rgba(0, 122, 255, 0.1);
            color: #007AFF;
        }
    }

    .emoji-icon {
        font-size: 24rpx;
        line-height: 1;
    }

    .message-input {
        flex: 1;
            height: 60rpx;
        font-size: 28rpx;
        background: transparent;
        border: none;
        outline: none;
            padding: 0 20rpx;
    }

    .send-btn {
        width: 60rpx;
        height: 60rpx;
        border-radius: 50%;
        background: #bfbfbf;
        display: flex;
        align-items: center;
        justify-content: center;
        transition: all 0.3s ease;

        &.active {
            background: linear-gradient(135deg, #95ec69, #5dd55c);
            transform: scale(1.05);
        }
    }

    /* 表情面板样式 */
    .emoji-panel {
        position: absolute;
        bottom: 100%;
        left: 0;
        right: 0;
        background: #fff;
        border-top: 1rpx solid #e5e5e5;
        border-radius: 20rpx 20rpx 0 0;
        box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.1);
        z-index: 200;
        max-height: 400rpx;
        transform: translateY(100%);
        opacity: 0;
        transition: all 0.3s ease;

        &.show {
            transform: translateY(0);
            opacity: 1;
        }
    }

    .emoji-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 20rpx 30rpx;
        border-bottom: 1rpx solid #e5e5e5;
    }

    .emoji-title {
            font-size: 28rpx;
        font-weight: 600;
        color: #333;
    }

    .emoji-close {
        width: 40rpx;
        height: 40rpx;
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        background: #f5f5f5;
        transition: all 0.3s ease;

        &:active {
            background: #e5e5e5;
            transform: scale(0.95);
        }
    }

    .emoji-list {
        height: 300rpx;
        padding: 20rpx;
    }

    .emoji-grid {
        display: grid;
        grid-template-columns: repeat(8, 1fr);
        gap: 8rpx;
        padding: 10rpx 0;
    }

    .emoji-item {
        width: 60rpx;
            height: 60rpx;
        display: flex;
        align-items: center;
        justify-content: center;
            font-size: 28rpx;
        border-radius: 8rpx;
        transition: all 0.2s ease;
        background: transparent;
        margin: 0 auto;

        &:active {
            background: #e3f2fd;
            transform: scale(0.85);
        }

        &:hover {
            background: #f5f5f5;
        }
    }

    /* 响应式适配 */
    @media screen and (max-width: 750rpx) {
        .message-bubble {
            max-width: 80%;
        }
    }
</style>